package com.spiro.gis.tiledownload;

import com.spiro.gis.tiledownload.common.HttpUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

/**
 * @Author: Shaoping Huang
 * @Description:
 * @Date: 1/14/2018
 */
public class TileDownloaderManager {

    private int parallelism;
    private String urlPattern;
    private String baseTargetDir;
    private BlockingQueue<TileCoordinate> queue;

    private List<TileDownloader> tileDownloaders = new ArrayList<>();
    private List<Thread> threads = new ArrayList<>();

    public TileDownloaderManager setParallelism(int parallelism) {
        this.parallelism = parallelism;
        return this;
    }

    public TileDownloaderManager setUrlPattern(String urlPattern) {
        this.urlPattern = urlPattern;
        return this;
    }

    public TileDownloaderManager setBaseTargetDir(String baseTargetDir) {
        this.baseTargetDir = baseTargetDir;
        return this;
    }

    public TileDownloaderManager setQueue(BlockingQueue<TileCoordinate> queue) {
        this.queue = queue;
        return this;
    }

    public void start() throws IOException {
        if (parallelism <= 0) {
            parallelism = 4;
        }

        if (urlPattern == null || urlPattern.isEmpty()) {
            throw new IllegalArgumentException("urlPattern should not be null or empty.");
        }

        if (baseTargetDir == null || baseTargetDir.isEmpty()) {
            throw new IllegalArgumentException("baseTargetDir should not be null or empty.");
        }

        if (queue == null) {
            throw new IllegalArgumentException("queue should not be null.");
        }

        System.out.println("parallelism: " + parallelism
                + ", urlPattern: " + urlPattern + ", baseTargetDir: " + baseTargetDir);

        // parse file suffix
        TileCoordinate testTc = new TileCoordinate(0, 0, 0);
        String testUrl = HttpUtils.buildImgUrl(urlPattern, testTc);
        String contentType = HttpUtils.getContentType(testUrl);
        String suffix = HttpUtils.getSuffix(contentType);
        if (suffix == null) {
            suffix = "";
        }
        System.out.println("Parse file suffix: testUrl=" + testUrl
                + ", contentType=" + contentType + ", suffix=" + suffix);

        for (int i = 0; i < parallelism; i++) {
            TileDownloader downloader = new TileDownloader(this.urlPattern, this.baseTargetDir, suffix, this.queue);
            tileDownloaders.add(downloader);
        }

        int i = 0;
        for (TileDownloader tileDownloader : tileDownloaders) {
            Thread t = new Thread(tileDownloader, "tileDownloader-" + (++i));
            threads.add(t);
            t.start();
        }
    }

    /**
     * Generator end notify
     */
    public void endNotify() {
        for (TileDownloader tileDownloader : tileDownloaders) {
            tileDownloader.setEndFlag(true);
        }
    }

    public void join() {
        for (Thread thread : threads) {
            try {
                thread.join();
            } catch (InterruptedException e) {
            }
        }
    }

    public long getDownloadCount() {
        long sum = 0;
        for (TileDownloader tileDownloader : tileDownloaders) {
            sum += tileDownloader.getDownloadCount();
        }

        return sum;
    }
}
